package com.health.service.impl;

import com.health.pojo.Product;
import com.health.service.ProductService;
import com.health.vo.PageResult;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.*;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ProductServiceImpl implements ProductService {

    @Resource
    private ElasticsearchRestTemplate restTemplate;

    /**
     *  page 页码
     *  size 大小
     *  name 商品名称
     *  merchant 商家名称
     * form 起始价格
     * to 结束价格
     * orderField 排序字段
     * orderType 排序方式
     */
    @Override
    public PageResult<Product> findPage(Integer page, Integer size, Map<String, String> params) {
        //需要判断params是否为空,否则使用该对象的方法时报异常
        if (params==null){
            params=new HashMap<>();
        }

        //bool查询
        BoolQueryBuilder boolQueryBuilder = getBoolQuery(params);

        //分页查询
        PageRequest pageRequest = PageRequest.of(page - 1, size);

        //sort排序查询
        //使用默认score排序
        SortBuilder sortBuilder = SortBuilders.scoreSort();
        //判断是否含有排序的参数,有的话则换掉排序方式
        if (StringUtils.hasText(params.get("orderField")) && StringUtils.hasText(params.get("orderType"))){
            //添加排序字段
            sortBuilder=SortBuilders.fieldSort(params.get("orderField"));
            //添加排序方式
            if (params.get("orderType").equals("adc")){
                sortBuilder.order(SortOrder.ASC);
            }else if (params.get("orderType").equals("desc")){
                sortBuilder.order(SortOrder.DESC);
            }
        }

        //高亮查询
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //添加高亮查询的参数
        highlightBuilder.field("name").field("merchant").preTags("<font color='red'>")
                .postTags("</font>");

        //创建query请求
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)//bool参数查询
                .withPageable(pageRequest)//分页查询携带分页参数
                .withSort(sortBuilder)//排序查询携带排序参数
                .withHighlightBuilder(highlightBuilder)//高亮查询携带参数
                .build();

        //查询
        SearchHits<Product> searchHits = restTemplate.search(searchQuery, Product.class);
        //查询总数
        long count = restTemplate.count(searchQuery, Product.class);

        //最终结果集
        List<Product> productList=new ArrayList<>();
        //添加高亮查询
        for (SearchHit<Product> searchHit : searchHits) {
            //获取普通结果
            Product product = searchHit.getContent();

            //获取高亮结果
            //name字段高亮设置
            List<String> nameList = searchHit.getHighlightField("name");
            if (nameList.size()>0) {
                String name_high = nameList.get(0);
                //设置product参数为高亮结果
                product.setName(name_high);
            }
            //merchant字段高亮设置
            List<String> merchantList = searchHit.getHighlightField("merchant");
            if (merchantList.size()>0){
                String merchant_high = merchantList.get(0);
                //设置对象属性为高亮
                product.setMerchant(merchant_high);
            }

            //添加修改后的product到集合
            productList.add(product);
        }


        //返回结果列表和查询总数
        return new PageResult<>(count,productList);
    }

    private BoolQueryBuilder getBoolQuery(Map<String, String> params) {
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //范围查询rangeQuery
        RangeQueryBuilder range = new RangeQueryBuilder("price");
        //添加范围参数-if判断动态添加
        if (StringUtils.hasText(params.get("from")))
        range.gte(params.get("from"));
        if (StringUtils.hasText(params.get("to")))
        range.lte(params.get("to"));

        //条件查询name,merchant
        if (StringUtils.hasText((CharSequence) params.get("name")))
        boolQueryBuilder.must(new MatchQueryBuilder("name",params.get("name")));
        if (StringUtils.hasText(params.get("merchant")))
        boolQueryBuilder.must(new MatchQueryBuilder("merchant",params.get("merchant")));
        //添加rangeQuery
        boolQueryBuilder.must(range);

        return boolQueryBuilder;
    }
}
